﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using System.IO;
using ESRI.ArcGIS.DataSourcesGDB;
using System.Collections;
using ESRI.ArcGIS.esriSystem;
using PlanningGIS.Util;
using PlanningGIS.Util.Log;

namespace PlanningGIS.ArcGIS
{
    /// <summary>
    /// 数据集操作类
    /// </summary>
    [ComVisible(true)]
    public class FeatureClassHelper
    {
        /// <summary>
        /// 根据过滤条件删除表中的记录。
        /// </summary>
        /// <param name="table">要删除的表或数据集IFeatureClass as ITable</param>
        /// <param name="whereClause">删除的数据所满足的条件</param>
        public static void DeleteSearchedRows(ITable table, string whereClause)
        {
            IQueryFilter queryfilter = string.IsNullOrEmpty(whereClause) ? null : new QueryFilter() { WhereClause = whereClause };
            table.DeleteSearchedRows(queryfilter);
        }

        /// <summary>
        /// 使用IRowBuffer将图层中的某一个字段设置为同一的值。
        /// </summary>
        /// <exception >字段不存在时抛出异常</exception>
        /// <param name="feauteclass">要更新的图层</param>
        /// <param name="wherecause">要更新的数据满足的条件</param>
        /// <param name="fieldname">要更新的字段</param>
        /// <param name="value">要设置的值</param>
        public static void UpdateFeatures(IFeatureClass feauteclass, string wherecause, string fieldname, object value)
        {
            int index = feauteclass.FindField(fieldname);
            if (index < 0) throw new Exception("字段" + fieldname + "不存在");
            IQueryFilter flt = new QueryFilter();
            flt.WhereClause = wherecause;
            flt.SubFields = fieldname;
            ITable table = feauteclass as ITable;
            IRowBuffer buffer = table.CreateRowBuffer();
            buffer.set_Value(index, value);
            table.UpdateSearchedRows(flt, buffer);
            Marshal.ReleaseComObject(flt);
        }

        /// <summary>
        /// 使用IRowBuffer为图层中的多个字段赋值。
        /// </summary>
        /// <exception >字段不存在时抛出异常</exception>
        /// <param name="feauteclass">要更新的图层</param>
        /// <param name="wherecause">要更新的数据满足的条件</param>
        /// <param name="field_value">要更新的字段_值</param>
        /// <remarks>注记要素类为复杂对象，在更新前必须使用IWorkspaceEdit开启编辑，否则会更新失败</remarks>
        public static void UpdateFeatures(IFeatureClass feauteclass, string wherecause, Dictionary<string, object> field_value)
        {
            string subfields = string.Empty;
            foreach (KeyValuePair<string, object> p in field_value)
            {
                int index = feauteclass.FindField(p.Key);
                if (index < 0) throw new Exception("字段" + p.Key + "不存在");
                subfields += p.Key + " ";
            }
            subfields = subfields.Trim().Replace(" ", ",");
            IQueryFilter flt = new QueryFilter();
            flt.WhereClause = wherecause;
            flt.SubFields = subfields;
            ITable pTable = feauteclass as ITable;
            IRowBuffer buffer = pTable.CreateRowBuffer();
            foreach (KeyValuePair<string, object> p in field_value)
            {
                int index = feauteclass.FindField(p.Key);
                buffer.set_Value(index, p.Value);
            }
            pTable.UpdateSearchedRows(flt, buffer);
            Marshal.ReleaseComObject(flt);
        }

        /// <summary>
        /// 更新图层中满足条件的记录的属性值，不能更新空间对象
        /// </summary>
        /// <remarks>使用ICursor.UpdateRow更新IRow，速度最快</remarks>
        /// <param name="feauteclass">要更新的图层</param>
        /// <param name="spatialfilter">查询条件</param>
        /// <param name="namevalues">要更新的属性</param>
        public static void UpdateFeatures(IFeatureClass feauteclass, ISpatialFilter spatialfilter, Dictionary<string, object> namevalues)
        {
            //速度最快，320条记录219ms
            ITable table = feauteclass as ITable;
            ICursor cursor = table.Update(spatialfilter, false);
            int count = table.RowCount(spatialfilter);
            IRow row = cursor.NextRow();
            Dictionary<int, object> indexs = new Dictionary<int, object>();
            foreach (KeyValuePair<string, object> kvp in namevalues)
            {
                int i = row.Fields.FindField(kvp.Key);
                if (i < 0) continue;
                indexs.Add(i, kvp.Value);
            }
            if (indexs.Count < 1) return;
            while (row != null)
            {
                foreach (KeyValuePair<int, object> kvp in indexs)
                {
                    row.set_Value(kvp.Key, kvp.Value);
                }
                cursor.UpdateRow(row);
                row = cursor.NextRow();
            }


            //速度居中320条记录34922ms
            //IFeatureCursor FCursor = feauteclass.Search(new QueryFilter(), false);
            //IFeature feature = FCursor.NextFeature();
            //int featureNum = feauteclass.FeatureCount(null);
            //for (int i = 0; i < featureNum; i++)
            //{
            //    feature.set_Value(2, i);
            //    feature.Store();
            //    feature = FCursor.NextFeature();
            //}

            //速度最慢，320条记录40297ms
            //for (int i = 0; i < pTable.RowCount(null); i++)
            //{
            //    pRow = pTable.GetRow(i);
            //    pRow.set_Value(2, i + 6);
            //    pRow.Store();
            //}
        }

        /// <summary>
        /// 将空间对象插入到图层中
        /// </summary>
        /// <param name="feauteclass">要新增到的图层</param>
        /// <param name="geometrys">要新增的空间对象</param>
        /// <param name="namevalues">空间对象的属性值</param>
        /// <returns></returns>
        public static void InsertFeatures(IFeatureClass feauteclass, List<IGeometry> geometrys, List<Dictionary<string, object>> namevalues)
        {
            int count = geometrys == null ? namevalues.Count : geometrys.Count;
            IFeatureCursor featureCursor = feauteclass.Insert(true);
            Dictionary<string, int> indexs = new Dictionary<string, int>();
            if (namevalues != null && namevalues.Count > 0)
            {
                foreach (KeyValuePair<string, object> kvp in namevalues[0])
                {
                    int i = feauteclass.FindField(kvp.Key);
                    if (i < 0) continue;
                    indexs.Add(kvp.Key, i);
                }
            }
            for (int i = 0; i < count; i++)
            {
                IFeatureBuffer featurebuffer = feauteclass.CreateFeatureBuffer();
                if (geometrys != null && geometrys.Count > 0)
                {
                    featurebuffer.Shape = geometrys[i];
                }
                if (namevalues != null && namevalues.Count > 0)
                {
                    foreach (KeyValuePair<string, int> kvp in indexs)
                    {
                        if (kvp.Key.Equals("Shape", StringComparison.CurrentCultureIgnoreCase)) continue;
                        object v = namevalues[i][kvp.Key];
                        if (v == null) continue;
                        try
                        {
                            if (!featurebuffer.Fields.get_Field(kvp.Value).Editable) continue;
                            featurebuffer.set_Value(kvp.Value, v);
                        }
                        catch
                        {
                            LogHelper.WriteLog("字段" + kvp.Key + "赋值失败，值和字段类型不匹配");
                        }
                        
                    }
                }
                featureCursor.InsertFeature(featurebuffer);
            }
            featureCursor.Flush();
        }

        /// <summary>
        /// 拷贝数据集中的数据到目标图层中
        /// </summary>
        /// <param name="feauteclass">拷贝到的图层</param>
        /// <param name="source">要拷贝的数据集</param>
        /// <param name="fieldMapping">拷贝到的图层与要拷贝的数据集的字段的名称映射：feauteclass.index , source.index 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="defaultValues">图层需要赋值的其它默认值，若操作人，操作时间等： feauteclass.Index ,  value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="existsFieldNames">需要检查的是否重复的字段名称，名称是feauteclass中的名称。若取出的值中有空值，则不作为判断条件</param>
        /// <param name="isReplace">是否替换重复的数据，默认为true替换，否则不做处理</param>
        /// <param name="getMessage">消息处理事件</param>
        public static void CopyFeatures(IFeatureClass feauteclass, IFeatureCursor source, IDictionary<int, int> fieldMapping = null,
            IDictionary<int, object> defaultValues = null, List<string> existsFieldNames = null, bool isReplace = true, MessageDelegate getMessage = null)
        {
            if (fieldMapping == null || fieldMapping.Count == 0) fieldMapping = GetFieldMapping(feauteclass.Fields, source.Fields);
            List<int> nameindexs = GetFieldMapping(feauteclass.Fields, existsFieldNames);
            bool isInsert = (existsFieldNames == null || existsFieldNames.Count == 0) ? true : false; //是否不检查重复而直接拷贝
            IFeatureCursor insertCursor = feauteclass.Insert(true);
            long count = 0;
            IFeature feature = null;
            bool hasz = feauteclass.HasZValue();
            while ((feature = source.NextFeature()) != null)
            {
                bool insert = true;
                if (isInsert) insert = true;
                else
                {
                    string where = "";
                    for (int i = 0; i < existsFieldNames.Count; i++)
                    {
                        object v = feature.get_Value(fieldMapping[nameindexs[i]]);
                        if (v == null) continue;
                        IField fd = feauteclass.Fields.get_Field(nameindexs[i]);
                        if (fd.Type == esriFieldType.esriFieldTypeInteger || fd.Type == esriFieldType.esriFieldTypeDouble ||
                           fd.Type == esriFieldType.esriFieldTypeSmallInteger || fd.Type == esriFieldType.esriFieldTypeSingle ||
                            fd.Type == esriFieldType.esriFieldTypeOID)
                            where += " and " + existsFieldNames[i] + " = " + v.ToString();
                        else if (fd.Type == esriFieldType.esriFieldTypeString)
                            where += " and " + existsFieldNames[i] + " = '" + v.ToString() + "' ";
                        else if (fd.Type == esriFieldType.esriFieldTypeDate)
                            where += " and " + existsFieldNames[i] + " = '" + v.ToString() + "' ";
                    }
                    if (!string.IsNullOrWhiteSpace(where))
                    {
                        IQueryFilter flt = new QueryFilter();
                        flt.WhereClause = where.Trim().Substring(3);
                        flt.SubFields = "*";
                        IFeatureCursor upCursor = feauteclass.Update(flt, false);
                        IFeature upFeat = null;
                        while ((upFeat = upCursor.NextFeature()) != null)
                        {
                            insert = false;
                            if (!isReplace) break;
                            CopyAttribute(upFeat, feature, fieldMapping, defaultValues);
                            upCursor.UpdateFeature(upFeat);
                        }
                        upCursor.Flush();
                        upCursor = null;
                    }
                    else
                    {
                        insert = true;
                    }
                }
                if (insert)
                {
                    IFeatureBuffer featureBuffer = feauteclass.CreateFeatureBuffer();
                    CopyFeature(feature, featureBuffer, fieldMapping, defaultValues, hasz, getMessage);//注记也可以直接复制
                    insertCursor.InsertFeature(featureBuffer);
                    if (++count % 1000 == 0) insertCursor.Flush();
                }
            }
            insertCursor.Flush();
            Marshal.FinalReleaseComObject(insertCursor);
            insertCursor = null;
        }

        /// <summary>
        /// 拷贝数据集中的数据到目标图层中
        /// </summary>
        /// <param name="feauteclass">拷贝到的图层</param>
        /// <param name="source">要拷贝的数据集</param>
        /// <param name="fieldMapping">对象的字段映射关系：to.index , from.index。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="otherValues">图层需要赋值的其它值： feauteclass.Index ,  value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="getMessage"></param>
        public static void CopyFeatures(IFeatureClass feauteclass, IFeatureSelection source, IDictionary<int, int> fieldMapping = null,
            IDictionary<int, object> otherValues = null, MessageDelegate getMessage = null)
        {
            ISelectionSet pSelectioSet = source.SelectionSet;
            if (pSelectioSet.Count == 0) return;
            IFeatureClass sourcelyr = (source as IFeatureLayer).FeatureClass;
            int index = -1;
            IEnumIDs pEnumIDs = pSelectioSet.IDs;
            IFeatureCursor insertCursor = feauteclass.Insert(true);
            long count = 0;
            bool hasz = feauteclass.HasZValue();
            while ((index = pEnumIDs.Next()) != -1)
            {
                IFeature feature = sourcelyr.GetFeature(index);
                IFeatureBuffer featureBuffer = feauteclass.CreateFeatureBuffer();
                CopyFeature(feature, featureBuffer, fieldMapping, otherValues, hasz, getMessage);
                insertCursor.InsertFeature(featureBuffer);
                if (++count % 1000 == 0)
                {
                    insertCursor.Flush();
                }
            }
            insertCursor.Flush();
            Marshal.FinalReleaseComObject(insertCursor);


        }

        /// <summary>
        /// 将空间对象复制到另一个对象中
        /// </summary>
        /// <param name="from">要复制的对象</param>
        /// <param name="to">复制到的对象</param>
        /// <param name="fieldMapping">对象的字段映射关系：to.index , from.index。可以通过GetFieldMapping取得索引映射关系 </param>
        /// <param name="otherValues">扩展的其它值：to.index , to.value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="zaware">是否有Z值</param>
        /// <param name="getMessage"></param>
        public static void CopyFeature(IFeature from, IFeatureBuffer to, IDictionary<int, int> fieldMapping = null, 
            IDictionary<int, object> otherValues = null, bool zaware = false, MessageDelegate getMessage = null)
        {
            CopyAttribute(from, to, fieldMapping, otherValues);
            if (from.ShapeCopy != null)
            {
                IGeometry geometry = from.ShapeCopy;
                (geometry as IZAware).ZAware = zaware;
                to.Shape = geometry;
            }
            else
            {
                if (getMessage != null) getMessage(string.Format("【{0}】空间对象为空", from.OID));
            }
        }

        /// <summary>
        /// 将空间对象复制到另一个对象中
        /// </summary>
        /// <param name="from">要复制的对象</param>
        /// <param name="to">复制到的对象</param>
        /// <param name="fieldMapping">对象的字段映射关系：to.index , from.index。可以通过GetFieldMapping取得索引映射关系 </param>
        /// <param name="otherValues">扩展的其它值：to.index , to.value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="zaware">是否有Z值</param>
        /// <param name="getMessage"></param>
        public static void CopyFeature(IFeature from, IFeature to, IDictionary<int, int> fieldMapping = null,
            IDictionary<int, object> otherValues = null, bool zaware = false, MessageDelegate getMessage = null)
        {
            CopyAttribute(from, to, fieldMapping, otherValues);
            if (from.ShapeCopy != null)
            {
                IGeometry geometry = from.ShapeCopy;
                (geometry as IZAware).ZAware = zaware;
                to.Shape = geometry;
            }
            else
            {
                if (getMessage != null) getMessage(string.Format("【{0}】空间对象为空", from.OID));
            } 
        }

        /// <summary>
        /// 将一个空间对象的属性复制到另一个空间对象中
        /// </summary>
        /// <param name="from">要复制的对象</param>
        /// <param name="to">复制到的对象</param>
        /// <param name="fieldMapping">对象的字段映射关系：to.index , from.index。可以通过GetFieldMapping取得索引映射关系 </param>
        /// <param name="otherValues">扩展的其它值：to.index , to.value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="getMessage"></param>
        public static void CopyAttribute(IFeature from, IFeatureBuffer to, IDictionary<int, int> fieldMapping = null,
            IDictionary<int, object> otherValues = null, MessageDelegate getMessage = null)
        {
            if (fieldMapping == null && otherValues == null)
            {
                int count = to.Fields.FieldCount;
                for (int i = 0; i < count; i++)
                {
                    IField f = to.Fields.get_Field(i);
                    if (f.Type == esriFieldType.esriFieldTypeGeometry || f.Type == esriFieldType.esriFieldTypeOID || !f.Editable)
                        continue;
                    int i2 = from.Fields.FindField(f.Name);
                    if (i2 < 0)
                    {
                        if (getMessage != null) getMessage("源图层中不存在字段" + f.Name);
                        continue;
                    }
                    object obj = from.get_Value(i2);
                    to.set_Value(i, obj);
                }
            }
            else
            {
                if (fieldMapping != null && fieldMapping.Count > 0)
                {
                    foreach (KeyValuePair<int, int> kvp in fieldMapping)
                    {
                        if (kvp.Value < 0 || kvp.Key < 0) continue;
                        object value = from.get_Value(kvp.Value);
                        to.set_Value(kvp.Key, value);
                    }
                }
                if (otherValues != null && otherValues.Count > 0)
                {
                    foreach (KeyValuePair<int, object> kvp in otherValues)
                    {
                        if (kvp.Key < 0) continue;
                        to.set_Value(kvp.Key, kvp.Value);
                    }
                }
            }
        }

        /// <summary>
        /// 将一个空间对象的属性复制到另一个空间对象中
        /// </summary>
        /// <param name="from">要复制的对象</param>
        /// <param name="to">复制到的对象</param>
        /// <param name="fieldMapping">对象的字段映射关系：to.index , from.index。可以通过GetFieldMapping取得索引映射关系 </param>
        /// <param name="otherValues">扩展的其它值：to.index , to.value 。可以通过GetFieldMapping取得索引映射关系</param>
        /// <param name="getMessage"></param>
        public static void CopyAttribute(IFeature from, IFeature to, IDictionary<int, int> fieldMapping = null,
            IDictionary<int, object> otherValues = null, MessageDelegate getMessage = null)
        {
            if (fieldMapping == null && otherValues == null)
            {
                int count = to.Fields.FieldCount;
                for (int i = 0; i < count; i++)
                {
                    IField f = to.Fields.get_Field(i);
                    if (f.Type == esriFieldType.esriFieldTypeGeometry || f.Type == esriFieldType.esriFieldTypeOID || !f.Editable)
                        continue;
                    int i2 = from.Fields.FindField(f.Name);
                    if (i2 < 0)
                    {
                        if (getMessage != null) getMessage("源图层中不存在字段" + f.Name);
                        continue;
                    }
                    object obj = from.get_Value(i2);
                    to.set_Value(i, obj);
                }
            }
            else
            {
                if (fieldMapping != null && fieldMapping.Count > 0)
                {
                    foreach (KeyValuePair<int, int> kvp in fieldMapping)
                    {
                        if (kvp.Value < 0 || kvp.Key < 0) continue;
                        object value = from.get_Value(kvp.Value);
                        if (!to.Fields.get_Field(kvp.Key).Editable) continue;
                        to.set_Value(kvp.Key, value);
                    }
                }
                if (otherValues != null && otherValues.Count > 0)
                {
                    foreach (KeyValuePair<int, object> kvp in otherValues)
                    {
                        if (kvp.Key < 0) continue;
                        if (!to.Fields.get_Field(kvp.Key).Editable) continue;
                        to.set_Value(kvp.Key, kvp.Value);
                    }
                }
            }
        }

        /// <summary>
        /// 复制注记对象，暂时不用
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        private static void CopyAnnotation(IFeature from, IFeatureBuffer to)
        {
            IAnnotationFeature pSrcAnnoFeature = from as IAnnotationFeature;
            IAnnotationFeature pTargetAnnoFeature = to as IAnnotationFeature;
            ITextElement pTxtElement = new TextElement() as ITextElement;
            pTxtElement.Text = ((ITextElement)pSrcAnnoFeature.Annotation).Text;
            IElement pElement = pTxtElement as IElement;
            pElement.Geometry = from.Shape.Envelope.LowerLeft;
            pTxtElement.Symbol = ((ITextElement)pSrcAnnoFeature.Annotation).Symbol;
            pTxtElement.Symbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
            pTxtElement.Symbol.VerticalAlignment = esriTextVerticalAlignment.esriTVACenter;
            pTargetAnnoFeature.Annotation = pTxtElement as IElement;
        }

        /// <summary>
        /// 获取字段1与字段2的字段索引关系。返回的结果为形式为fields1.index,fields2.index。
        /// 调用方式：
        /// 1.IFields - IFields全字段的映射：GetFieldMapping(fields1,fields2);
        /// 2.IFields - IFields指定字段映射：GetFieldMapping(fields1,fields2,fieldNameMapping);
        /// 3.IFields - IFields全字段与指定字段同时映射GetFieldMapping(fields1,fields2,fieldNameMapping,true);
        /// </summary>
        /// <param name="fields1">要映射到的图层字段</param>
        /// <param name="fields2">源字段</param>
        /// <param name="fieldNameMapping">fields1.Name,fields2.Name</param>
        /// <param name="isBoth">是否同时存在</param>
        /// <returns></returns>
        public static IDictionary<int, int> GetFieldMapping(IFields fields1, IFields fields2,
            IDictionary<string, string> fieldNameMapping = null, bool isBoth = false)
        {
            IDictionary<int, int> fieldIndexMapping = new Dictionary<int, int>();
            if (fieldNameMapping == null || isBoth)
            {
                int count = fields1.FieldCount;
                for (int i = 0; i < count; i++)
                {
                    IField f = fields1.get_Field(i);
                    if (f.Type == esriFieldType.esriFieldTypeGeometry || f.Type == esriFieldType.esriFieldTypeOID)
                        continue;
                    if (!f.Editable)
                        continue;
                    int index2 = fields2.FindField(f.Name);
                    if (index2 < 0)
                    {
                        continue;
                    }
                    fieldIndexMapping.Add(i, index2);
                }
            }
            if (fieldNameMapping != null && fieldNameMapping.Count > 0)
            {
                foreach (KeyValuePair<string, string> kvp in fieldNameMapping)
                {
                    if (string.IsNullOrEmpty(kvp.Key) || string.IsNullOrEmpty(kvp.Value)) continue;
                    int sourceIndex = fields1.FindField(kvp.Key);
                    if (sourceIndex < 0)
                    {
                        continue;
                    }
                    int targetIndex = fields2.FindField(kvp.Value);
                    if (targetIndex < 0)
                    {
                        continue;
                    }
                    if (fieldIndexMapping.ContainsKey(sourceIndex)) continue;
                    fieldIndexMapping.Add(sourceIndex, targetIndex);
                }
            }
            return fieldIndexMapping;
        }

        /// <summary>
        /// 获取属性值字段名称与图层字段的索引映射关系
        /// </summary>
        /// <param name="fields">要映射到的图层字段</param>
        /// <param name="otherValues">扩展的其它值：to.Name , to.value</param>
        /// <returns></returns>
        public static IDictionary<int, object> GetFieldMapping(IFields fields, IDictionary<string, object> otherValues)
        {
            if (otherValues == null || otherValues.Count == 0) return null;
            IDictionary<int, object> fieldIndexMapping = new Dictionary<int, object>();
            foreach (KeyValuePair<string, object> kvp in otherValues)
            {
                if (string.IsNullOrEmpty(kvp.Key)) continue;
                int index = fields.FindField(kvp.Key);
                if (index < 0) continue;
                fieldIndexMapping.Add(index, kvp.Value);
            }
            return fieldIndexMapping;
        }

        /// <summary>
        /// 获取属性值字段名称与图层字段的索引映射关系
        /// </summary>
        /// <param name="fields">要映射到的图层字段</param>
        /// <param name="names">字段名称</param>
        /// <returns></returns>
        public static List<int> GetFieldMapping(IFields fields, List<string> names)
        {
            if (names == null || names.Count == 0) return null;
            List<int> fieldIndexMapping = new List<int>();
            foreach (string s in names)
            {
                if (string.IsNullOrWhiteSpace(s)) continue;
                int index = fields.FindField(s);
                if (index < 0)
                {
                    continue;
                }
                fieldIndexMapping.Add(index);
            }
            return fieldIndexMapping;
        }

        /// <summary>
        /// 挖除要素类层中的polygon的范围内的数据，
        /// 在使用过程前必须先用拓扑接口对传入的polygon进行简单化（Simplify）。需要改进，使用store是更新比较慢
        /// </summary>
        /// <param name="polygon"></param>
        /// <param name="featureClass"></param>
        /// <returns></returns>
        public static void ExcavateFeatureLayer(IPolygon polygon, IFeatureClass featureClass)
        {
            //查找完全被pPolygon包涵的要素，并删除找到的要素
            ISpatialFilter pFilter = new SpatialFilter();
            pFilter.Geometry = polygon;
            pFilter.GeometryField = featureClass.ShapeFieldName;
            pFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
            IFeatureCursor pFeatureCursor = featureClass.Search(pFilter, false);
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                pFeature.Delete();
                pFeature = pFeatureCursor.NextFeature();
            }

            //求pPolygon的边界线，查找与边界线相交的要素，对找到的要素的图形与pPolygon求差
            IPolyline pPolyline = polygon.ToPolyline();
            pFilter = new SpatialFilter();
            pFilter.Geometry = pPolyline;
            pFilter.GeometryField = featureClass.ShapeFieldName;
            pFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
            pFeatureCursor = featureClass.Search(pFilter, false);
            pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                ITopologicalOperator pTopoOp = (ITopologicalOperator)pFeature.Shape;
                IGeometry pGeoResult = pTopoOp.Difference(polygon);
                IGeometry pGeoResult3D = GeometryHelper.Geom2Dto3D(pGeoResult);
                pFeature.Shape = pGeoResult3D;
                pFeature.Store();
                pFeature = pFeatureCursor.NextFeature();
            }

            ////查找完全包涵pPolygon的要素，对找到的要素的图形与pPolygon求差
            pFilter = new SpatialFilter();
            pFilter.Geometry = polygon;
            pFilter.GeometryField = featureClass.ShapeFieldName;
            pFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
            pFeatureCursor = featureClass.Search(pFilter, false);
            pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                ITopologicalOperator pTopoOp = (ITopologicalOperator)pFeature.Shape;
                IGeometry pGeoResult = pTopoOp.Difference(polygon);
                IGeometry pGeoResult3D = GeometryHelper.Geom2Dto3D(pGeoResult);
                pFeature.Shape = pGeoResult3D;
                pFeature.Store();
                pFeature = pFeatureCursor.NextFeature();
            }

        }

        /// <summary>
        /// 获取图层上满足过滤条件的个数，执行本操作后，该图层上的选择集将被清空
        /// </summary>
        /// <param name="featLyr"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static int GetFeatureCountFromLayer(IFeatureLayer featLyr, IQueryFilter filter)
        {
            return featLyr.FeatureClass.FeatureCount(filter);
            //IFeatureSelection featSel = featLyr as IFeatureSelection;
            //featSel.SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultNew, false);
            //int count = featSel.SelectionSet.Count;
            //featSel.Clear();
            //return count;
        }

        /// <summary>
        /// 根据空间位置或查询条件查找指定的图层中是否相应的空间对象，若存在则返回相应的IFeatureCursor，否则返回空
        /// </summary>
        /// <param name="featcls">图层</param>
        /// <param name="where">查询条件，与空间位置不能同时为空</param> 
        /// <param name="geometry">要查找的空间位置，与查询条件不能同时为空</param>
        /// <param name="spatialRel">空间关系</param>
        /// <param name="buffer">空间位置的缓冲区,大于或等于0</param>
        /// <returns>若存在则返回相应的对像，否则返回空</returns>
        public static IFeatureCursor ExistFeatureCursor(IFeatureClass featcls, string where, IGeometry geometry, esriSpatialRelEnum spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects, double buffer = 0)
        {
            if (featcls == null) return null;
            ISpatialFilter spatialFilter = new SpatialFilter();
            spatialFilter.GeometryField = featcls.ShapeFieldName;
            if (geometry != null && geometry.IsEmpty == false)
            {
                spatialFilter.Geometry = GeometryHelper.GetBuffer(geometry, buffer);
                spatialFilter.SpatialRel = spatialRel;
                spatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
            }
            if (!string.IsNullOrWhiteSpace(where))
            {
                spatialFilter.WhereClause = where;
            }
            IFeatureCursor pFC = featcls.Search(spatialFilter, false);
            return pFC;
        }
    }
}
